import UIKit
import ImageIO

extension UIImage {
    
    struct ImageCircleBorder {
        private(set) var width: CGFloat = 1
        private(set) var color = UIColor.whiteColor()
        
        init(borderWidth: CGFloat, boderColor: UIColor) {
            width = borderWidth
            color = boderColor
        }
    }
    
    // MARK: - GIF图片动画
    class func animatedGIFFirstFrameWithData(data: NSData) -> UIImage? {
        if data.length == 0 {
            return nil
        }
        
        let dataPtr = CFDataCreate(kCFAllocatorDefault, UnsafePointer<UInt8>(data.bytes), data.length)
        let source = CGImageSourceCreateWithData(dataPtr, nil)!
        let count = CGImageSourceGetCount(source)
        let animatedImage: UIImage?
        if count <= 1 {
            return UIImage(data: data)
        }
        
        var images: [UIImage] = []
        let cgimage = CGImageSourceCreateImageAtIndex(source, 0, nil)!
        let image = UIImage(CGImage: cgimage, scale: UIScreen.mainScreen().scale, orientation: .Up)
        images.append(image)
        animatedImage = images.first
        return animatedImage
    }
    
    class func animatedGIFWithData(data: NSData) -> UIImage?  {
        if data.length == 0 {
            return nil
        }
        
        let dataPtr = CFDataCreate(kCFAllocatorDefault, UnsafePointer<UInt8>(data.bytes), data.length)
        let source = CGImageSourceCreateWithData(dataPtr, nil)!
        let count = CGImageSourceGetCount(source)
        let animatedImage: UIImage?
        if count <= 1 {
            return UIImage(data: data)
        }
        
        var images: [UIImage] = []
        var duration: Double = 0.0
        
        for i in 0...count {
            let cgimage = CGImageSourceCreateImageAtIndex(source, 0, nil)!
            let frameProperties = CGImageSourceCopyPropertiesAtIndex(source, i, nil)! as NSDictionary
            let time = frameProperties.objectForKey(kCGImagePropertyGIFDictionary)?.objectForKey(kCGImagePropertyGIFDelayTime)?.doubleValue
            
            duration = duration + time!
            let image = UIImage(CGImage: cgimage, scale: UIScreen.mainScreen().scale, orientation: .Up)
            images.append(image)
        }
        
        if duration > 0.0 {
            duration = (0.1) * Double(count)
        }
        
        animatedImage = UIImage.animatedImageWithImages(images, duration: duration)
        return animatedImage
    }
    
    class func animatedGIFNamed(name: String, isFirst: Bool) -> UIImage?  {
        let scale = UIScreen.mainScreen().scale;
        var retinaPath = NSBundle.mainBundle().pathForResource(name + "@2x", ofType: "gif")
        
        if scale > 1.0 {
            let data = NSData(contentsOfFile:retinaPath!)
            if (data?.length > 0) {
                return UIImage.animatedGIFWithData(data!)
            }
        }
        
        retinaPath = NSBundle.mainBundle().pathForResource(name, ofType: "gif")
        let data = NSData(contentsOfFile:retinaPath!)
        if (data?.length > 0) {
            if isFirst {
                return UIImage.animatedGIFWithData(data!)
            }
            return UIImage.animatedGIFFirstFrameWithData(data!)
        }
        
        return UIImage(named: name)
    }
    
    // MARK: - 图片裁剪圆脑袋
    /** 根据当前图片切圆 */
    func circleImage() -> UIImage {
        // false代表透明
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        // 获得上下文
        let ctx = UIGraphicsGetCurrentContext()
        // 添加一个圆
        let rect = CGRectMake(0, 0, size.width, size.height)
        CGContextAddEllipseInRect(ctx, rect)
        // 裁剪
        CGContextClip(ctx)
        // 将图片画上去
        drawInRect(rect)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return image
    }
    
    /**
     *  图片裁剪成圆形头像(用上下文方式)
     *
     *  @param border 边框
     *
     *  @return 圆形图片
     */
    func circleImage(border: ImageCircleBorder) -> UIImage {
        /// 1.开启一个位图上下文
        // 开启位图上下文
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        /// 2.获取当前上下文
        // 获取上下文
        let contxtRef = UIGraphicsGetCurrentContext()
        
        /// 3.画一个大圆，描述边框
        // 外层圆的半径
        let radius = size.width * 0.5;
        // 中心点的x、y
        let centerX = size.width * 0.5;
        let centerY = size.height * 0.5
        
        // 在上下文添加一个大圆
        CGContextAddArc(contxtRef, centerX, centerY, radius, 0, 2.0 * CGFloat(M_PI), 0)
        // 背景颜色填充整个圆
        border.color.setFill()
        // 描绘描述的圆
        CGContextFillPath(contxtRef)
        
        /// 4.画一个小圆，为了显示图片
        // 小圆的半径
        let innerRadius = radius - border.width
        // 在上下文添加一个小圆
        CGContextAddArc(contxtRef, centerX, centerY, innerRadius, 0, 2.0 * CGFloat(M_PI), 0)
        // 裁剪后面的图片
        CGContextClip(contxtRef)
        // 图片画上去的位置、大小
        let drawInRectXY = border.width * 0.5
        let imageRect = CGRectMake(drawInRectXY, drawInRectXY, size.width - border.width, size.height - border.width)
        drawInRect(imageRect)
        
        /// 5.获取上下文中图片
        let circleImage = UIGraphicsGetImageFromCurrentImageContext()
        /// 6. 关闭上下文
        UIGraphicsEndImageContext()
        
        return circleImage
    }
    
    /**
     *  根据传过来的图片名，把图片裁剪成圆形头像
     *
     *  @param name    图片名
     *  @param border  边框
     *
     *  @return 圆形图片
     */
    class func circleImage(name: String, border: ImageCircleBorder) -> UIImage {
        let image = UIImage(named: name)
    
        return image!.circleImage(border)
    }
    
    /**
     *  图片裁剪成圆形头像(用Bezier方式)
     *
     *  @param borderWidth 边框半径
     *  @param borderColor 边框颜色
     *
     *  @return 圆形图片
     */
    func circleImageBezier(border: ImageCircleBorder) -> UIImage {
        /// 1.开启一个位图上下文
        // 图层山下文大小
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0);
        
        /// 2.画一个大圆，描述边框
        // 外层圆的半径
        let radius = size.width * 0.5;
        // 中心点的x、y
        let centerX = size.width * 0.5;
        let centerY = size.height * 0.5
        
        let pointCenter = CGPointMake(centerX, centerY)
        var path = UIBezierPath(arcCenter: pointCenter, radius: radius, startAngle: 0, endAngle: 2.0 * CGFloat(M_PI), clockwise: true)
        border.color.setFill()
        path.fill()
        
        /// 3.画一个小圆，为了显示图片
        // 小圆的半径
        let innerRadius = radius - border.width
        path = UIBezierPath(arcCenter: pointCenter, radius: innerRadius, startAngle: 0, endAngle: 2.0 * CGFloat(M_PI), clockwise: true)
        
        // 裁剪后面的图片
        path.addClip()
        let imageRect = CGRectMake(0.0, 0.0, size.width - border.width, size.height - border.width)
        drawInRect(imageRect)
        
        /// 4.获取上下文中图片
        let circleImage = UIGraphicsGetImageFromCurrentImageContext()
        
        /// 5. 关闭上下文
        UIGraphicsEndImageContext()
        
        return circleImage
    }
    
    // MARK: - 拉伸 > 以图片中心位置1像素拉伸图片
    class func imageStretchWithImageName(imageName: String) -> UIImage? {
        let image = UIImage(named: imageName)
        
        return image?.stretchImageWithLocationCenterPoint()
    }
    
    func stretchImageWithLocationCenterPoint() -> UIImage {
        let w = Int(size.width * 0.5)
        let h = Int(size.height * 0.5)
        
        return stretchableImageWithLeftCapWidth(w, topCapHeight: h)
    }
    
    // MARK: - 图片水印
    /**
     *  为图片添加文本水印
     *
     *  @param name  图片名
     *  @param text  文本
     *  @param textRext 文本位置大小
     *  @param textAttribute  文本样式
     *
     *  @return 水印图片
     */
    class func imageWaterAndString(imageName: String, text: NSString, textRext: CGRect, textAttribute: [String : AnyObject]) -> UIImage? {
        let image = UIImage(named: imageName)
        
        return image?.waterString(text, textRext: textRext, textAttribute: textAttribute)
    }
    
    func waterString(text: NSString, textRext: CGRect, textAttribute: [String : AnyObject]) -> UIImage {
        // 开启一个位图上下文
        /// size: 开启的位图上下文大小
        /// opaque:是否不透明
        /// scale:缩放多少,一般不缩放＝0
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        // 把图片画到上下文中
        drawInRect(CGRectMake(0, 0, size.width, size.height))
        // 把文字画到上下文中
        text.drawInRect(textRext, withAttributes: textAttribute)
        // 获取图片
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        // 关闭当前上下文
        UIGraphicsEndImageContext()
        
        return newImage
    }
    
    // MARK: - 从大图上截取指定位置图片
    /**
     *  从大图上截取指定位置图片
     *
     *  @param bigImage 原始图片
     *  @param rect     截取的大小位置
     *
     *  @return 返回一个从原图上截取的新图片
     */
    class func cropImage(originalImage: UIImage, cropRect: CGRect) -> UIImage {
        let ref = CGImageCreateWithImageInRect(originalImage.CGImage, cropRect)!
        
        return UIImage(CGImage: ref)
    }
    
    func cropImage(rect: CGRect) -> UIImage {
        return UIImage.cropImage(self, cropRect: rect)
    }
    
    /**
     *  按图片大小平均截取
     *
     *  @param bigImage  截取的原始图片
     *  @param num 截取的个数
     *
     *  @return 返回一个装在全部小图片的数组
     */
    class func cropImage(originalImage: UIImage, num: Int) -> [UIImage] {
        // 获取屏幕的像素与点的比例
        let screenScale = UIScreen.mainScreen().scale
        // 获取每个小图片的宽度
        let smallImageW = originalImage.size.width / CGFloat(num) * screenScale
        // 获取图片的高度
        let smallImageH = originalImage.size.height * screenScale;
        // 用来存储每个小图片
        var smallImageArray = [UIImage]()
        
        for i in 0..<num {
            // 每个图片的矩形大小
            let smallRect = CGRectMake((CGFloat(i) * smallImageW), 0, smallImageW, smallImageH)
            // 小图
            let newImage = cropImage(originalImage,cropRect: smallRect)
            // 截取图片添加到数组中
            smallImageArray.append(newImage)
        }
        // 返回全部的小图片
        return smallImageArray;
    }
}
